﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Mvc;

namespace Sharp.Portal.Mvc.Bootstrap
{
    /// <summary>
    /// DropdownList。
    /// </summary>
    public class DropdownListBuilder : TagElementBuilder<DropdownListBuilder>
    {

        private readonly TypeConfiguration _typeConfiguration;
        private readonly DropdownListSizeConfiguration _dropdownListSizeConfiguration;
        private readonly DropdownListStyleConfiguration _dropdownListStyleConfiguration;

        public DropdownListBuilder()
        {
            _typeConfiguration = new TypeConfiguration(this);
            _dropdownListSizeConfiguration = new DropdownListSizeConfiguration(this);
            _dropdownListStyleConfiguration = new DropdownListStyleConfiguration(this);
            AddClass("btn-group").AddClass("dropdown").Style();
            Inputtype = "radio";
            Simple = false;
        }


        /// <summary>
        /// 标题
        /// </summary>
        public string Title
        {
            get => TagBuilder.InnerHtml;
            set => TagBuilder.SetInnerText(value);
        }


        public TypeConfiguration Type()
        {
            return _typeConfiguration;
        }

        public DropdownListSizeConfiguration Size()
        {
            return _dropdownListSizeConfiguration;
        }

        public DropdownListBuilder Active(bool? active = null)
        {
            if (active.HasValue)
                return active.Value ? AddClass("active") : RemoveClass("active");

            return ToggleClass("active");
        }

        public DropdownListBuilder Disabled(bool disabled = true)
        {
            if (disabled)
                return Attribute("disabled", "disabled", true);
            TagBuilder.Attributes.Remove("disabled");
            return this;
        }

        public DropdownListStyleConfiguration Style()
        {
            return _dropdownListStyleConfiguration;
        }


        public DropdownListBuilder Click(string click)
        {
            return Attribute("onclick", click, true);
        }

        public override string TagName => "DropdownList";

        /// <summary>
        /// 数据源
        /// </summary>
        public IEnumerable DataSource { get; set; }

        public string DisplayField { get; set; }
        public string ValueField { get; set; }

        public string SelectedValue { get; set; }
        /// <summary>
        /// 简单样式（录入界面用的）
        /// </summary>
        public bool Simple { get; set; }
        /// <summary>
        /// 多选
        /// </summary>
        public bool Multiple { get; set; }
        /// <summary>
        /// 备注
        /// </summary>
        public string Description { get; set; }

        /// <inheritdoc />
        /// <summary>
        /// 返回 HTML 编码的字符串。
        /// </summary>
        /// <returns>
        /// HTML 编码的字符串。
        /// </returns>
        public override string ToHtmlString()
        {
            var name = this.TagBuilder.Attributes.Keys.Contains("name")
                ? this.TagBuilder.Attributes["name"]
                : this.TagBuilder.Attributes["id"];

            var builder = new StringBuilder(10 * 1024);

            builder.AppendLine(TagBuilder.ToString(TagRenderMode.StartTag).Replace(TagName, "div"));

            if (Simple)
            {
                builder.AppendFormat(@"<button data-toggle=""dropdown"" class=""btn btn-default dropdown-toggle form-control"">
                    <input class=""dropdown-label"" data-validation="".dropdown"" value=""{{SelectedText}}"" id=""{1}label"" name=""{1}label"" {0} />
                    <span class=""caret""></span>
                  </button>", GetValidationAttributes(), name);
            }
            else
            {
                builder.AppendFormat(@"<button data-toggle=""dropdown"" class=""btn btn-sm btn-default dropdown-toggle form-control"">
                    <input class=""dropdown-label pull-left wrapper-sm"" data-validation="".dropdown"" value=""{{SelectedText}}"" id=""{1}label"" name=""{1}label"" {0} />
                    <span class=""btn-caret pull-right""><span class=""caret""></span></span>
                  </button>", GetValidationAttributes(), name);

            }
            builder.AppendLine("<ul class=\"dropdown-menu dropdown-select btn-ul scrollable\" style=\"max-height:375px;\">");

            if (!this.Multiple)
                builder.AppendFormat("<li><a href=\"#\"><input type=\"{2}\" value=\"\" name=\"{0}\" />{1}</a></li>", TagBuilder.Attributes["name"], Description.IsNullOrEmpty() ? "　" : Description, Inputtype);

            if (this.DataSource != null)
            {
                foreach (var item in this.DataSource)
                {
                    var type = item.GetType();
                    if (type == typeof(Enum))
                    {
                        DataSourceItemEnum(builder);
                    }
                    else if (!type.IsValueType && type != typeof(string))
                    {
                        DataSourceItemReferenceType(builder);
                    }
                    else
                    {
                        DataSourceItemCommon(builder);
                    }
                    break;
                }
            }

            builder.AppendLine("</ul>");
            builder.AppendLine(TagBuilder.ToString(TagRenderMode.EndTag).Replace(TagName, "div"));

            //如果还没被替换掉，将发挥作用
            builder.Replace("{SelectedText}", this.Title);

            return new HtmlString(builder.ToString()).ToHtmlString();
        }

        public string Inputtype { set; get; }

        private void DataSourceItemReferenceType(StringBuilder builder)
        {
            if (this.DisplayField.IsNullOrEmpty())
            {
                throw new NotImplementedException("DisplayField属性未赋值");
            }
            else
            {
                if (this.ValueField.IsNullOrEmpty())
                {
                    this.ValueField = this.DisplayField;
                }
            }
            #region 实体类

            if (this.SelectedValue == null)
            {
                this.SelectedValue = string.Empty;
            }
            var selectedValues = SelectedValue.Split(',');
            var selectedText = new List<string>();

            foreach (var v in selectedValues)
            {
                foreach (var o in this.DataSource)
                {
                    var valueFieldProperty = o.GetType().GetProperty(ValueField);
                    var displayFieldProperty = o.GetType().GetProperty(DisplayField);

                    object text = displayFieldProperty.GetValue(o, null);
                    object value = valueFieldProperty.GetValue(o, null);


                    var name = this.TagBuilder.Attributes.Keys.Contains("name")
                        ? this.TagBuilder.Attributes["name"]
                        : this.TagBuilder.Attributes["id"];
                    if (value.ToString() == v)
                    {
                        selectedText.Add(text.ToString());

                        builder.Append("\r\n<li class=\"active\">");
                        builder.AppendFormat(
                            "<a href=\"javascript:void(0)\"><input type=\"{3}\" checked=\"checked\" name=\"{2}\" value=\"{0}\">{1}</a></li>\r\n",
                            value, text, name, Inputtype);
                    }
                    else
                    {
                        builder.Append("\r\n<li>");
                        builder.AppendFormat(
                            "<a href=\"javascript:void(0)\"><input type=\"{3}\" name=\"{2}\" value=\"{0}\">{1}</a></li>\r\n",
                            value, text, name, Inputtype);

                    }
                }
            }
            builder.Replace("{SelectedText}", string.Join(",", selectedText.ToArray()));

            #endregion
        }

        private void DataSourceItemCommon(StringBuilder builder)
        {
            if (this.SelectedValue == null)
            {
                this.SelectedValue = string.Empty;
            }
            var selectedValues = SelectedValue.Split(',');
            var selectedText = new List<string>();

            foreach (var v in selectedValues)
            {
                foreach (var item in this.DataSource)
                {
                    var name = this.TagBuilder.Attributes.Keys.Contains("name")
                        ? this.TagBuilder.Attributes["name"]
                        : this.TagBuilder.Attributes["id"];
                    if (item.ToString() == v)
                    {
                        selectedText.Add(item.ToString());

                        builder.Append("\r\n<li class=\"active\">");

                        builder.AppendFormat(
                            "<a href=\"javascript:void(0)\"><input type=\"{3}\" checked=\"checked\" name=\"{2}\" value=\"{0}\">{1}</a></li>\r\n",
                            item, item, name, Inputtype);
                    }
                    else
                    {
                        builder.Append("<li>");
                        builder.AppendFormat(
                            "<a href=\"javascript:void(0)\"><input type=\"{3}\" name=\"{2}\" value=\"{0}\">{1}</a></li>\r\n",
                            item, item, name, Inputtype);
                    }
                }
            }
            builder.Replace("{SelectedText}", string.Join(",", selectedText.ToArray()));

        }

        private void DataSourceItemEnum(StringBuilder builder)
        {
            #region 枚举

            if (this.SelectedValue == null)
            {
                this.SelectedValue = string.Empty;
            }
            var selectedValues = SelectedValue.Split(',');
            var selectedText = new List<string>();

            foreach (var v in selectedValues)
            {
                foreach (Enum item in this.DataSource)
                {
                    var name = this.TagBuilder.Attributes.Keys.Contains("name")
                        ? this.TagBuilder.Attributes["name"]
                        : this.TagBuilder.Attributes["id"];
                    if (Convert.ToInt32(item).ToString() == v)
                    {
                        selectedText.Add(item.GetDescription());

                        builder.Append("\r\n<li class=\"active\">");

                        builder.AppendFormat(
                            "<a href=\"javascript:void(0)\"><input type=\"{3}\" checked=\"checked\" name=\"{2}\" value=\"{0}\">{1}</a></li>\r\n",
                            Convert.ToInt32(item), item.GetDescription(), name, Inputtype);
                    }
                    else
                    {
                        builder.Append("<li>");
                        builder.AppendFormat(
                            "<a href=\"javascript:void(0)\"><input type=\"{3}\" name=\"{2}\" value=\"{0}\">{1}</a></li>\r\n",
                            Convert.ToInt32(item), item.GetDescription(), name, Inputtype);
                    }
                }
            }
            builder.Replace("{SelectedText}", string.Join(",", selectedText.ToArray()));
            #endregion
        }
        public IDictionary<string, object> ValidationAttributes { get; set; }

        private string GetValidationAttributes()
        {
            if (ValidationAttributes == null) return string.Empty;

            StringBuilder sb = new StringBuilder();
            foreach (var attribute in ValidationAttributes)
            {
                sb.AppendFormat("{0}=\"{1}\"", attribute.Key, attribute.Value.ToString());
            }
            return sb.ToString();
        }
        /// <summary>
        /// 返回表示当前 <see cref="T:System.Object"/> 的 <see cref="T:System.String"/>。
        /// </summary>
        /// <returns>
        /// <see cref="T:System.String"/>，表示当前的 <see cref="T:System.Object"/>。
        /// </returns>
        public override string ToString()
        {
            return ToHtmlString();
        }

        public sealed class TypeConfiguration
        {
            private readonly DropdownListBuilder _dropdownListBuilder;

            public TypeConfiguration(DropdownListBuilder dropdownListBuilder)
            {
                _dropdownListBuilder = dropdownListBuilder;
                //DropdownList();
            }

            //public DropdownListBuilder DropdownList()
            //{
            //    return _dropdownListBuilder.Attribute("type", "DropdownList", true);
            //}

        }

        public sealed class DropdownListSizeConfiguration : SizeConfiguration<DropdownListBuilder>
        {
            public DropdownListSizeConfiguration(DropdownListBuilder tagElementBuilder)
                : base("btn", tagElementBuilder)
            {
            }

            public DropdownListBuilder ExtraSmall()
            {
                Value = "btn-xs";
                return TagElementBuilder;
            }
        }

        public sealed class DropdownListStyleConfiguration : StyleConfiguration<DropdownListBuilder>
        {
            public DropdownListStyleConfiguration(DropdownListBuilder instance)
                : base("btn", instance)
            {
            }

            public DropdownListBuilder Link()
            {
                Value = "btn-link";

                return Instance;
            }
        }

    }
}